package ch9;

import util.Debug;
import util.Tools;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 计划执行任务Demo
 * 在 Execution Time 始终不长于 delay或者period所代表的时间的情况下，
 * scheduleAtFixedRate和scheduleWithFixedDelay能够按照固定的时间-2s，来执行
 *
 * 在 Execution Time长于dealy或者period所代表的时间的情况下，
 * scheduleAtFixedRate和scheduleWithFixedDelay都无法保证任务以固定的周期执行
 */

public class ScheduledTaskDemo {
    static ScheduledExecutorService ses = Executors.newScheduledThreadPool(2);

    public static void main(String[] args) throws InterruptedException {
        final int argc = args.length;
        // 任务执行最大耗时
        int maxConsumption;
        // 任务执行最小耗时
        int minConsumption;
        if (argc >= 2) {
            minConsumption = Integer.valueOf(args[0]);
            maxConsumption = Integer.valueOf(args[1]);
        } else {
            maxConsumption = minConsumption = 1000;
        }
        ses.scheduleAtFixedRate(new SimulatedTask(minConsumption, maxConsumption, "scheduleAtFixdRate"),
                0, 2, TimeUnit.SECONDS);
        ses.scheduleWithFixedDelay(new SimulatedTask(minConsumption, maxConsumption, "scheduleWithFixedDelay"),
                0, 1, TimeUnit.SECONDS);
        Thread.sleep(20000);

        ses.shutdown();
    }

    static class SimulatedTask implements Runnable {
        private String name;
        // 模拟任务执行耗时
        private final int maxConsumption;
        private final int minConsumption;
        private final AtomicInteger seq = new AtomicInteger(0);

        public SimulatedTask(int minConsumption, int maxConsumption, String name) {
            this.minConsumption = minConsumption;
            this.maxConsumption = maxConsumption;
            this.name = name;
        }

        @Override
        public void run() {
            try {
                // 模拟执行任务
                Tools.randomPause(maxConsumption, minConsumption);
                Debug.info(name + "run-" + seq.incrementAndGet());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
